/*
 * PhotonRTOS础光实时操作系统 -- 调度表测试代码
 *
 * Copyright (C) 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Lin Yang <s-yanglin@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include "../utest.h"


TEST(GetScheduleTableStatus)
{
	VAR(TickType, AUTOMATIC) value;
	VAR(StatusType, AUTOMATIC) st;
	VAR(ScheduleTableStatusType, AUTOMATIC) schedtbl_st;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00293] ⌈如果GetScheduleTableStatus ()调用中的标识符 <ScheduleTableID>无效，则 GetScheduleTableStatus()应返回E_OS_ID 。 ⌋ ( )
	 */
	st = GetScheduleTableStatus(AUTOSAR_NR_SCHEDULE_TABLE, &schedtbl_st);
	ASSERT_EQ(st, E_OS_ID);
#endif

	/**
	 * [SWS_Os_00289] ⌈如果调用GetScheduleTableStatus ()中的调度表 <ScheduleTableID>未启动，则 GetScheduleTableStatus()应通过参考参数 <ScheduleStatus>传回SCHEDULETABLE_STOPPED并返回E_OK 。 ⌋ ( )
	 */
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_STOPPED);

	/**
	 * [SWS_Os_00353] ⌈如果 GetScheduleTableStatus () 调用中的调度表 <ScheduleTableID> 在NextScheduleTable ()调用中使用并等待当前调度表结束， GetScheduleTableStatus()应通过参考参数 <ScheduleStatus>返回SCHEDULETABLE_NEXT AND 应返回E_OK 。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareScheduleTable(1, 15, 15, 2, NO_SYNC, 0);
	DeclareExpiryPoint(0, 3, 0, 0, 0);
	DeclareExpiryPoint(1, 3, 1, 0, 0);
	st = StartScheduleTableRel(0, value);
	ASSERT_EQ(st, E_OK);
	st = NextScheduleTable(0, 1);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(1, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_NEXT);

#if defined(AUTOSAR_SYNCHRONIZATION_SUPPORT)
	/**
	 * [SWS_Os_00354] ⌈如果调用GetScheduleTableStatus () 中的调度表 <ScheduleTableID> 配置了显式同步，并且 <ScheduleTableID> 是使用StartScheduleTableSynchron()启动的，并且没有向操作系统提供同步计数， GetScheduleTableStatus()将返回SCHEDULETABLE_WAITING通过参考参数 <ScheduleStatus> 并且应返回E_OK 。 ⌋ ( )
	 */
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, EXPLICIT, 0);
	DeclareExpiryPoint(0, 3, 0, 0, 0);
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_WAITING);

	/**
	 * [SWS_Os_00290] ⌈如果调用GetScheduleTableStatus ()中的调度表 <ScheduleTableID>已启动且同步，则 GetScheduleTableStatus()应通过参考参数 <ScheduleStatus>传回SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS并返回E_OK 。 ⌋ ( )
	 */
	value = 0;
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, EXPLICIT, 0);
	DeclareExpiryPoint(0, 3, 0, 0, 0);
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OK);
	st = SyncScheduleTable(0, value);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS);

	/**
	 * [SWS_Os_00291] ⌈如果调用GetScheduleTableStatus () 中的调度表 <ScheduleTableID> 已启动且不同步（偏差不在精度区间内或调度表已设置为异步），则GetScheduleTableStatus()应通过参考参数 ScheduleStatus 返回 SCHEDULETABLE_RUNNING 并应返回E_OK 。 ⌋ ( )
	 */
	value = 0;
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, EXPLICIT, 2);
	DeclareExpiryPoint(0, 3, 0, 0, 0);
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OK);
	st = SyncScheduleTable(0, value);
	ASSERT_EQ(st, E_OK);
	st = SetScheduleTableAsync(0);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING);

	st = SyncScheduleTable(0, value);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS);
	value = 7;
	st = SyncScheduleTable(0, value);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING);
#endif /* defined(AUTOSAR_SYNCHRONIZATION_SUPPORT) */

	/**
	 * [SWS_Os_00528] ⌈ GetScheduleTableStatus()的可用性：可用于所有可扩展性类。 ⌋ ( )
	 */

}

TEST(StartScheduleTableRel)
{
	VAR(TickType, AUTOMATIC) value;
	VAR(StatusType, AUTOMATIC) st;
	VAR(ScheduleTableStatusType, AUTOMATIC) schedtbl_st;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00275] ⌈如果StartScheduleTableRel()调用中的调度表 <ScheduleTableID>无效，则 StartScheduleTableRel()应返回E_OS_ID 。 ⌋ ( )
	 */
	value = 2;
	st = StartScheduleTableRel(AUTOSAR_NR_SCHEDULE_TABLE, value);
	ASSERT_EQ(st, E_OS_ID);

#if defined(AUTOSAR_SYNCHRONIZATION_SUPPORT)
	/**
	 * [SWS_Os_00452] ⌈如果调度表 <ScheduleTableID> 在StartScheduleTableRel()的调用中是隐式同步的（ OsScheduleTblSyncStrategy   = IMPLICIT )，则 StartScheduleTableRel()应返回E_OS_ID 。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, IMPLICIT_SYNC, 0);
	st = StartScheduleTableRel(0, value);
	ASSERT_EQ(st, E_OS_ID);
#endif /* defined(AUTOSAR_SYNCHRONIZATION_SUPPORT) */

	/**
	 * [SWS_Os_00332] ⌈如果StartScheduleTableRel()调用中的 <Offset>为零，则StartScheduleTableRel()应返回E_OS_VALUE 。 ⌋ ( )
	 */
	value = 0;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	st = StartScheduleTableRel(0, value);
	ASSERT_EQ(st, E_OS_VALUE);

	/**
	 * [SWS_Os_00276] ⌈如果偏移量 <Offset> ) 大于底层计数器的OsCounterMaxAllowedValue减去初始偏移量， StartScheduleTableRel()应返回E_OS_VALUE 。 ⌋ ( )
	 */
	value = 10;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	st = StartScheduleTableRel(0, value);
	ASSERT_EQ(st, E_OS_VALUE);
#endif

	/**
	 * [SWS_Os_00277] ⌈如果StartScheduleTableRel()调用中的调度表 <ScheduleTableID>不处于状态SCHEDULETABLE_STOPPED ，则 StartScheduleTableRel()应返回E_OS_STATE 。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	autosar_schedule_tables[0].status = SCHEDULETABLE_RUNNING;
	st = StartScheduleTableRel(0, value);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_NEXT;
	st = StartScheduleTableRel(0, value);
	ASSERT_EQ(st, E_OS_STATE);

#if defined(AUTOSAR_SYNCHRONIZATION_SUPPORT)
	autosar_schedule_tables[0].status = SCHEDULETABLE_WAITING;
	st = StartScheduleTableRel(0, value);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS;
	st = StartScheduleTableRel(0, value);
	ASSERT_EQ(st, E_OS_STATE);
#endif /* defined(AUTOSAR_SYNCHRONIZATION_SUPPORT) */

	/**
	 * [SWS_Os_00278] ⌈如果StartScheduleTableRel()的输入参数有效且调度表 <ScheduleTableID> 的状态为SCHEDULETABLE_STOPPED ，则StartScheduleTableRel()应开始处理调度表 <ScheduleTableID>。初始到期点应在基础计数器上经过 <Offset> + Initial Offset 刻度后处理。 <ScheduleTableID> 的状态在服务返回给调用者之前设置为SCHEDULETABLE_RUNNING 。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	st = StartScheduleTableRel(0, value);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING);

	/**
	 * [SWS_Os_00521] ⌈ StartScheduleTableRel()的可用性：可用于所有可伸缩性类。 ⌋ ( )
	 */

}

TEST(StartScheduleTableAbs)
{
	VAR(TickType, AUTOMATIC) value;
	VAR(StatusType, AUTOMATIC) st;
	VAR(ScheduleTableStatusType, AUTOMATIC) schedtbl_st;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00348] ⌈如果StartScheduleTableAbs()调用中的调度表 <ScheduleTableID>无效，则 StartScheduleTableAbs()应返回E_OS_ID 。 ⌋ ( )
	 */
	value = 2;
	st = StartScheduleTableAbs(AUTOSAR_NR_SCHEDULE_TABLE, value);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * [SWS_Os_00349] ⌈如果StartScheduleTableAbs()调用中的 <Start>大于底层计数器的OsCounterMaxAllowedValue ，则StartScheduleTableAbs()应返回E_OS_VALUE 。 ⌋ ( )
	 */
	value = 20;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OS_VALUE);
#endif

	/**
	 * [SWS_Os_00350] ⌈如果StartScheduleTableAbs()调用中的调度表 <ScheduleTableID>不处于状态SCHEDULETABLE_STOPPED ，则 StartScheduleTableAbs()应返回E_OS_STATE 。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);

	autosar_schedule_tables[0].status = SCHEDULETABLE_RUNNING;
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_NEXT;
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OS_STATE);

#if defined(AUTOSAR_SYNCHRONIZATION_SUPPORT)
	autosar_schedule_tables[0].status = SCHEDULETABLE_WAITING;
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS;
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OS_STATE);
#endif /* defined(AUTOSAR_SYNCHRONIZATION_SUPPORT) */

	/**
	 * [SWS_Os_00351] ⌈如果StartScheduleTableAbs()的输入参数有效且 <ScheduleTableID> 处于状态SCHEDULETABLE_STOPPED ，则 StartScheduleTableAbs()将在底层计数器下一个等于 <Start> 时开始处理调度表 <ScheduleTableID> 并设置<ScheduleTableID> 的状态为
	 *      SCHEDULETABLE_RUNNING （用于非同步/显式同步的调度表）或
	 *      SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS （用于隐式同步的调度表）
	 * 在返回给用户之前。 （当底层计数器下一个等于
	 *  <Start>+Initial Offset 时，将处理初始到期点）。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING);

#if defined(AUTOSAR_SYNCHRONIZATION_SUPPORT)
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, IMPLICIT_SYNC, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS);
#endif /* defined(AUTOSAR_SYNCHRONIZATION_SUPPORT) */

	/**
	 * [SWS_Os_00522] ⌈ StartScheduleTableAbs()的可用性：可用于所有可扩展性类。 ⌋ ( )
	 */
}

TEST(StopScheduleTable)
{
	VAR(TickType, AUTOMATIC) value;
	VAR(StatusType, AUTOMATIC) st;
	VAR(ScheduleTableStatusType, AUTOMATIC) schedtbl_st;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00279] ⌈如果调度表标识符 <ScheduleTableID> 在调用StopScheduleTable()无效，则 StopScheduleTable()应返回E_OS_ID 。 ⌋ ( )
	 */
	st = StopScheduleTable(AUTOSAR_NR_SCHEDULE_TABLE);
	ASSERT_EQ(st, E_OS_ID);
#endif

	/**
	 * [SWS_Os_00281] ⌈如果StopScheduleTable()的输入参数有效， StopScheduleTable()应将 <ScheduleTableID> 的状态设置为SCHEDULETABLE_STOPPED并且（停止调度表 <ScheduleTableID> 处理任何进一步的到期点并且）应返回E_OK 。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING);
	st = StopScheduleTable(0);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_STOPPED);

	/**
	 * [SWS_Os_00280] ⌈如果在调用StopScheduleTable()时标识符为 <ScheduleTableID> 的调度表处于SCHEDULETABLE_STOPPED状态，则 StopScheduleTable()应返回E_OS_NOFUNC 。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING);
	st = StopScheduleTable(0);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_STOPPED);
	st = StopScheduleTable(0);
	ASSERT_EQ(st, E_OS_NOFUNC);

	/**
	 * [SWS_Os_00523] ⌈ StopScheduleTable()的可用性：可用于所有可扩展性类。 ⌋ ( )
	 */

}

TEST(NextScheduleTable)
{
	VAR(TickType, AUTOMATIC) value;
	VAR(StatusType, AUTOMATIC) st;
	VAR(ScheduleTableStatusType, AUTOMATIC) schedtbl_st;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00282] ⌈如果NextScheduleTable()调用中的输入参数 <ScheduleTableID_From> 或 <ScheduleTableID_To>无效，则 NextScheduleTable()应返回E_OS_ID 。 ⌋ ( )
	 */
	st = NextScheduleTable(0, AUTOSAR_NR_SCHEDULE_TABLE);
	ASSERT_EQ(st, E_OS_ID);

	st = NextScheduleTable(AUTOSAR_NR_SCHEDULE_TABLE, 0);
	ASSERT_EQ(st, E_OS_ID);

	st = NextScheduleTable(AUTOSAR_NR_SCHEDULE_TABLE, AUTOSAR_NR_SCHEDULE_TABLE);
	ASSERT_EQ(st, E_OS_ID);

#if defined(AUTOSAR_SYNCHRONIZATION_SUPPORT)
	/**
	 * [SWS_Os_00484] ⌈如果在NextScheduleTable ()调用中 <ScheduleTableID_To> 的OsScheduleTblSyncStrategy不等于<ScheduleTableID_From> 的 OsScheduleTblSyncStrategy 则NextScheduleTable()应返回E_OS_ID 。 ⌋ ( )
	 */
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 12, 13, 2, NO_SYNC, 0);
	DeclareScheduleTable(1, 12, 13, 2, EXPLICIT, 0);
	DeclareScheduleTable(2, 12, 13, 2, IMPLICIT_SYNC, 0);
	st = NextScheduleTable(0, 1);
	ASSERT_EQ(st, E_OS_ID);
	st = NextScheduleTable(0, 2);
	ASSERT_EQ(st, E_OS_ID);
	st = NextScheduleTable(1, 2);
	ASSERT_EQ(st, E_OS_ID);
#endif /* defined(AUTOSAR_SYNCHRONIZATION_SUPPORT) */

	/**
	 * [SWS_Os_00330] ⌈如果调用NextScheduleTable()调度表 <ScheduleTableID_To> 由与调度表 <ScheduleTableID_From> 不同的计数器驱动，则NextScheduleTable()将返回错误E_OS_ID 。 ⌋ ( )
	 */
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareCounter(3, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareScheduleTable(1, 15, 15, 3, NO_SYNC, 0);
	st = NextScheduleTable(0, 1);
	ASSERT_EQ(st, E_OS_ID);
#endif

	/**
	 * [SWS_Os_00283] ⌈如果NextScheduleTable()调用中的调度表 <ScheduleTableID_From> 处于SCHEDULETABLE_STOPPED状态或处于SCHEDULETABLE_NEXT状态，则 NextScheduleTable()应保持 <ScheduleTable_From> 和 <ScheduleTable_To> 的状态不变并返回E_OS_NOFUNC 。 ⌋ ( )
	 */
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareScheduleTable(1, 15, 15, 2, NO_SYNC, 0);
	autosar_schedule_tables[0].status = SCHEDULETABLE_STOPPED;
	st = NextScheduleTable(0, 1);
	ASSERT_EQ(st, E_OS_NOFUNC);

	autosar_schedule_tables[0].status = SCHEDULETABLE_NEXT;
	st = NextScheduleTable(0, 1);
	ASSERT_EQ(st, E_OS_NOFUNC);

	/**
	 * [SWS_Os_00309] ⌈如果NextScheduleTable()调用中的调度表 <ScheduleTableID_To>不处于状态SCHEDULETABLE_STOPPED ，则 NextScheduleTable()应保持 <ScheduleTable_From> 和 <ScheduleTable_To> 的状态不变并返回E_OS_STATE 。 ⌋ ( )
	 */
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareScheduleTable(1, 15, 15, 2, NO_SYNC, 0);
	autosar_schedule_tables[0].status = SCHEDULETABLE_RUNNING;
	autosar_schedule_tables[1].status = SCHEDULETABLE_RUNNING;
	st = NextScheduleTable(0, 1);
	ASSERT_EQ(st, E_OS_STATE);


	/**
	 * [SWS_Os_00324] ⌈如果NextScheduleTable()的输入参数有效并且 <ScheduleTableID_From> 已经有一个“下一个”调度表，则NextScheduleTable()将用 <ScheduleTableID_To> 替换之前的“下一个”调度表并更改旧的“下一个”调度表状态为SCHEDULETABLE_STOPPED 。 ⌋ ( )
	 */
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareScheduleTable(1, 15, 15, 2, NO_SYNC, 0);
	DeclareScheduleTable(2, 15, 15, 2, NO_SYNC, 0);
	autosar_schedule_tables[0].status = SCHEDULETABLE_RUNNING;
	st = NextScheduleTable(0, 1);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(1, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_NEXT);
	st = NextScheduleTable(0, 2);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(1, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_STOPPED);
	st = GetScheduleTableStatus(2, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_NEXT);

	/**
	 * [SWS_Os_00453] ⌈如果NextScheduleTable()调用中的 < ScheduleTableID_From>停止，则 NextScheduleTable()不应启动“下一个”调度表并将其状态更改为SCHEDULETABLE_STOPPED 。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 1024, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	DeclareScheduleTable(1, 15, 15, 2, NO_SYNC, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	st = StartScheduleTableAbs(0, value);
	ASSERT_EQ(st, E_OK);
	st = NextScheduleTable(0, 1);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(1, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_NEXT);
	st = StopScheduleTable(0);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(1, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_STOPPED);

	/**
	 * [SWS_Os_00505] ⌈如果在NextScheduleTable ()调用中调度表 <ScheduleTableID_From> 和 <ScheduleTableID_To> 的OsScheduleTblSyncStrategy是EXPLICIT并且操作系统模块已经同步 <ScheduleTableID_From>，则 NextScheduleTable()将在处理开始后继续同步 <ScheduleTableID_To >。 ⌋ ( )
	 */

	/**
	 * [SWS_Os_00284] ⌈如果NextScheduleTable()的输入参数有效，则NextScheduleTable()应开始处理调度表 <ScheduleTableID_To> <ScheduleTableID_From>.FinalDelay 在处理完 <ScheduleTableID_From> 上的最终到期点后tick并返回E_OK 。 NextScheduleTable()应在 <ScheduleTableID_From> 处处理 <ScheduleTableID_To> 上的 Initial Expiry Point。Final Delay + <ScheduleTable_To>.Initial Offset 在处理完 <ScheduleTableID_From> 上的 Final Expiry Point 之后tick作响应。 ⌋ ( )
	 */

	/**
	 * [SWS_Os_00524] ⌈ NextScheduleTable()的可用性：可用于所有可扩展性类。 ⌋ ( )
	 */

}

#if defined(AUTOSAR_SYNCHRONIZATION_SUPPORT)
TEST(StartScheduleTableSynchron)
{
	VAR(StatusType, AUTOMATIC) st;
	VAR(ScheduleTableStatusType, AUTOMATIC) schedtbl_st;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00387] ⌈如果在调用StartScheduleTableSynchron()时调度表 <ScheduleTableID> 无效或调度表 <ScheduleTableID> 未显式同步 ( OsScheduleTblSyncStrategy ! = EXPLICIT) StartScheduleTableSynchron()应返回E_OS_ID 。 ⌋ ( )
	 */
	st = StartScheduleTableSynchron(AUTOSAR_NR_SCHEDULE_TABLE);
	ASSERT_EQ(st, E_OS_ID);

	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OS_ID);
#endif

	/**
	 * [SWS_Os_00388] ⌈如果StartScheduleTableSynchron()调用中的调度表 <ScheduleTableID>不处于状态SCHEDULETABLE_STOPPED ，则 StartScheduleTableSynchron()应返回E_OS_STATE 。 ⌋ ( )
	 */
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, EXPLICIT, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	autosar_schedule_tables[0].status = SCHEDULETABLE_WAITING;
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_RUNNING;
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS;
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_NEXT;
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OS_STATE);

	/**
	 * [SWS_Os_00389] ⌈如果<ScheduleTableID> 在StartScheduleTableSynchron()调用时有效， StartScheduleTableSynchron()应设置<ScheduleTableID> 的状态为SCHEDULETABLE_WAITING并在通过SyncScheduleTable()设置调度表的同步计数后开始处理调度表<ScheduleTableID> 。当同步计数器上的 (Duration-SyncValue)+InitialOffset tick已经过去时，应处理初始到期点，其中：
	 * 持续时间是 <ScheduleTableID>.OsScheduleTableDuration
	 * SyncValue 是传递给SyncScheduleTable()的 <Value> 参数
	 * InitialOffset是 <ScheduleTableID> 中最短的过期点偏移量 ⌋ ( )
	 */
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, EXPLICIT, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_WAITING);

	/**
	 * [SWS_Os_00525] ⌈ StartScheduleTableSynchron()的可用性：在可扩展性类 2 和 4 中可用。⌋ ( )
	 */

}

TEST(SyncScheduleTable)
{
	VAR(TickType, AUTOMATIC) value;
	VAR(StatusType, AUTOMATIC) st;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00454] ⌈如果SyncScheduleTable()调用中的 <ScheduleTableID>无效或无法显式同步调度表（ OsScheduleTblSyncStrategy不等于EXPLICIT ） ，则 SyncScheduleTable()应返回E_OS_ID 。 ⌋ ( )
	 */
	value = 2;
	st = SyncScheduleTable(AUTOSAR_NR_SCHEDULE_TABLE, value);
	ASSERT_EQ(st, E_OS_ID);

	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	st = SyncScheduleTable(AUTOSAR_NR_SCHEDULE_TABLE, value);
	ASSERT_EQ(st, E_OS_ID);

	/**
	 * [SWS_Os_00455] ⌈如果SyncScheduleTable()调用中的 <Value>大于或等于OsScheduleTableDuration ，则 SyncScheduleTable()应返回E_OS_VALUE 。 ⌋ ( )
	 */
	value = 16;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, EXPLICIT, 0);
	st = SyncScheduleTable(0, value);
	ASSERT_EQ(st, E_OS_VALUE);
#endif

	/**
	 * [SWS_Os_00456] ⌈如果调度表 <ScheduleTableID> 的状态在调用SyncScheduleTable() 等于SCHEDULETABLE_STOPPED 或SCHEDULETABLE_NEXT SyncScheduleTable()应返回E_OS_STATE 。 ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, EXPLICIT, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	autosar_schedule_tables[0].status = SCHEDULETABLE_STOPPED;
	st = SyncScheduleTable(0, value);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_NEXT;
	st = SyncScheduleTable(0, value);
	ASSERT_EQ(st, E_OS_STATE);

	/**
	 * [SWS_Os_00457] ⌈如果SyncScheduleTable()调用中的参数有效，则 SyncScheduleTable()应向操作系统模块提供给定调度表的当前同步计数。 （用于将调度表的处理同步到同步计数器。） ⌋ （ )
	 */


	/**
	 * [SWS_Os_00526] ⌈ SyncScheduleTable()的可用性：在可扩展性类 2 和 4 中可用。⌋ ( )
	 */

}

TEST(SetScheduleTableAsync)
{
	VAR(TickType, AUTOMATIC) value;
	VAR(StatusType, AUTOMATIC) st;
	VAR(ScheduleTableStatusType, AUTOMATIC) schedtbl_st;

#if defined(EXTENDED_STATUS)
	/**
	 * [SWS_Os_00458] ⌈如果 SetScheduleTableAsync () 调用中 <ScheduleTableID> 的OsScheduleTblSyncStrategy不等于EXPLICIT 或如果 <ScheduleTableID> 无效，则SetScheduleTableAsync () 应返回E_OS_ID 。 ⌋ ( )
	 */
	st = SetScheduleTableAsync(AUTOSAR_NR_SCHEDULE_TABLE);
	ASSERT_EQ(st, E_OS_ID);

	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, NO_SYNC, 0);
	st = SetScheduleTableAsync(0);
	ASSERT_EQ(st, E_OS_ID);
#endif

	/**
	 * [SWS_Os_00483] ⌈如果在SetScheduleTableAsync ()调用中 <ScheduleTableID> 的当前状态等于SCHEDULETABLE_STOPPED、 SCHEDULETABLE_NEXT或 SCHEDULETABLE_WAITING然后SetScheduleTableAsync()应返回E_OS_STATE 。 ⌋ ( )
	 */
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, EXPLICIT, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	autosar_schedule_tables[0].status = SCHEDULETABLE_STOPPED;
	st = SetScheduleTableAsync(0);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_NEXT;
	st = SetScheduleTableAsync(0);
	ASSERT_EQ(st, E_OS_STATE);

	autosar_schedule_tables[0].status = SCHEDULETABLE_WAITING;
	st = SetScheduleTableAsync(0);
	ASSERT_EQ(st, E_OS_STATE);

	/**
	 * [SWS_Os_00300] ⌈如果在SetScheduleTableAsync ()调用中 <ScheduleTableID> 的当前状态等于SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS （或SCHEDULETABLE_RUNNING） ，则SetScheduleTableAsync()应设置（或在SCHEDULETABLE_RUNNING的情况下保持）<ScheduleTableID>的状态为SCHEDULETABLE_RUNNING ⌋ ( )
	 */
	value = 2;
	DeclareCounter(2, 18, 2, 1, SOFTWARE);
	DeclareScheduleTable(0, 15, 15, 2, EXPLICIT, 0);
	DeclareExpiryPoint(0, 10, 0, 0, 0);
	st = StartScheduleTableSynchron(0);
	ASSERT_EQ(st, E_OK);
	st = SyncScheduleTable(0, value);
	ASSERT_EQ(st, E_OK);
	st = SetScheduleTableAsync(0);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING);

	st = SetScheduleTableAsync(0);
	ASSERT_EQ(st, E_OK);
	st = GetScheduleTableStatus(0, &schedtbl_st);
	ASSERT_EQ(st, E_OK);
	ASSERT_EQ(schedtbl_st, SCHEDULETABLE_RUNNING);

	/**
	 * [SWS_Os_00362] ⌈如果为正在运行的调度表调用SetScheduleTableAsync ()，操作系统模块将停止进一步同步，直到调用SyncScheduleTable ()。 ⌋ ( )
	 */


	/**
	 * [SWS_Os_00323] ⌈如果为正在运行的调度表调用SetScheduleTableAsync ()，则操作系统模块应继续处理调度表上的到期点。 ⌋ ( )
	 */


	/**
	 * [SWS_Os_00527] ⌈ SetScheduleTableAsync()的可用性：在可伸缩性类 2 和 4 中可用。⌋ ( )
	 */

}
#endif /* defined(AUTOSAR_SYNCHRONIZATION_SUPPORT) */


TEST_SUIT(ScheduleTable)
{
	UTEST_CASE(GetScheduleTableStatus);
	UTEST_CASE(StartScheduleTableRel);
	UTEST_CASE(StartScheduleTableAbs);
	UTEST_CASE(StopScheduleTable);
	UTEST_CASE(NextScheduleTable);
#if defined(AUTOSAR_SYNCHRONIZATION_SUPPORT)
	UTEST_CASE(StartScheduleTableSynchron);
	UTEST_CASE(SyncScheduleTable);
	UTEST_CASE(SetScheduleTableAsync);
#endif /* defined(AUTOSAR_SYNCHRONIZATION_SUPPORT) */
}
